﻿/*
* YanGant 甘特图插件
* Copyright 2011, 刘玉宏
* 2011-05-10 v1.0	编写
/          zydata: ['总图', '建筑', '结构', '工艺', '水', '电控', '暖通', '经济'],
*/

(function ($) {
    var DateMethod = null;
    $.fn.YanGant = function (options) {
        var gantobj, gantabletobj, gantbody, thisTable = null; //甘特图框架
        var defaults = {
            zydata: ['总图', '建筑', '建筑1', '结构', '工艺', '水', '电控', '暖通', '经济'],
            startdate: "2012-04-20",
            enddate: "2012-05-20",
            tablewidth: "100", //table宽度
            colmModel: "", //列模型
            gantWidth: "1000", //甘特图宽度  
            gantHeight: "460", //甘特图高度
            chattype: "day", //数据跨度day:天 week:周
            cellwidth: "40", //时间列宽度
            expandlev: '1', //默认展开级别
            cellheight: "40", //行高
            usetip: true, //是否使用默认的任务提示信息
            gantcomplete: null,
            tdclick: null,
            inittd:null
        };
        thisTable = $(this);
        var options = $.extend(defaults, options);
         DateMethod = {
            //格式化日期
            format: function (date, str) {
                str = str.replace(/yyyy|YYYY/, date.getFullYear());
                str = str.replace(/MM/, date.getMonth() >= 9 ? ((date.getMonth() + 1) * 1).toString() : '0' + (date.getMonth() + 1) * 1);
                str = str.replace(/dd|DD/, date.getDate() > 9 ? date.getDate().toString() : '0' + date.getDate());
                return str;
            },
            //两个日期间的天数,-数为小于，正数为大于
            daysBetween: function (start, end) {
                var OneMonth = start.substring(5, start.lastIndexOf('-'));
                var OneDay = start.substring(start.length, start.lastIndexOf('-') + 1);
                var OneYear = start.substring(0, start.indexOf('-'));
                var TwoMonth = end.substring(5, end.lastIndexOf('-'));
                var TwoDay = end.substring(end.length, end.lastIndexOf('-') + 1);
                var TwoYear = end.substring(0, end.indexOf('-'));
                var cha = ((Date.parse(TwoMonth + '/' + TwoDay + '/' + TwoYear) - Date.parse(OneMonth + '/' + OneDay + '/' + OneYear)) / 86400000);
                return cha;
            },
            //判断是否周末
            isWeekend: function (date) {
                return date.getDay() % 6 === 0;
            },

            //判断是否周一
            isWeekstr: function (date) {
                return date.getDay() === 1;
            },
            //日期计算
            DateAdd: function (date, strInterval, Number) {
                var dtTmp = date;
                switch (strInterval) {
                    case 's': return new Date(Date.parse(dtTmp) + (1000 * Number));

                    case 'n': return new Date(Date.parse(dtTmp) + (60000 * Number));

                    case 'h': return new Date(Date.parse(dtTmp) + (3600000 * Number));

                    case 'd': return new Date(Date.parse(dtTmp) + (86400000 * Number));

                    case 'w': return new Date(Date.parse(dtTmp) + ((86400000 * 7) * Number));

                    case 'q': return new Date(dtTmp.getFullYear(), (dtTmp.getMonth()) + Number * 3, dtTmp.getDate(), dtTmp.getHours(), dtTmp.getMinutes(), dtTmp.getSeconds());

                    case 'm': return new Date(dtTmp.getFullYear(), (dtTmp.getMonth()) + Number, dtTmp.getDate(), dtTmp.getHours(), dtTmp.getMinutes(), dtTmp.getSeconds());

                    case 'y': return new Date((dtTmp.getFullYear() + Number), dtTmp.getMonth(), dtTmp.getDate(), dtTmp.getHours(), dtTmp.getMinutes(), dtTmp.getSeconds());
                }
                return date;
            },
            getMonths: function (start, end) {
                start = Date.parse(start); end = Date.parse(end);
                var months = [];
                months[start.getMonth()] = [start];
                var last = start;
                while (last.compareTo(end) === -1) {
                    var next = last.clone().addDays(1);
                    if (!months[next.getMonth()]) { months[next.getMonth()] = []; }
                    months[next.getMonth()].push(next);
                    last = next;
                }
                return months;
            },
            getDays: function (year, month) {
                var days = 30;
                if (month === "02")
                    days = 28;
                if ((",01,03,05,07,08,10,12,").indexOf("," + month + ",") > -1)
                    days = 31;
                if (month == "02" && parseInt(year) % 4 === 0 && !(parseInt(year) % 100 === 0 && !(parseInt(year) % 400 === 0)))
                    days = 29;
                return days;
            },
            StringToDate: function (DateStr) {
                var converted = Date.parse(DateStr);
                var myDate = new Date(converted);
                if (isNaN(myDate)) {
                    //var delimCahar = DateStr.indexOf('/')!=-1?'/':'-';
                    var arys = DateStr.split('-');
                    myDate = new Date(arys[0], --arys[1], arys[2]);
                }
                return myDate;
            },
            //获取日期为某年的第几周
            GetWeekIndex: function (datestr) {
                var dateobj = this.StringToDate(datestr);
                var firstDay = this.GetFirstWeekBegDay(dateobj.getFullYear());
                if (dateobj < firstDay) {
                    firstDay = this.GetFirstWeekBegDay(dateobj.getFullYear() - 1);
                }
                d = Math.floor((dateobj.valueOf() - firstDay.valueOf()) / 86400000);
                return Math.floor(d / 7) + 1;
            },
            //获取某年的第一天
            GetFirstWeekBegDay: function (year) {
                var tempdate = new Date(year, 0, 1);
                var temp = tempdate.getDay();
                if (temp === 1) {
                    return tempdate;
                }
                temp = temp === 0 ? 7 : temp;
                tempdate = tempdate.setDate(tempdate.getDate() + (8 - temp));
                return new Date(tempdate);
            }
        };
        var YanGantMethod = {
            //添加任务甘特图
            addGantBody: function (chattype) {
                //将一格的宽度加一（包括边框的一像素）
                var startdate = options.startdate;
                //var enddate = DateMethod.format(DateMethod.DateAdd(DateMethod.StringToDate(options.startdate), 'm', 1), "YYYY-MM-DD");
                var enddate = options.enddate;
                var cellWidth = options.cellwidth * 1;
                var cellheight = options.cellheight * 1;
                var gantHeight = options.gantHeight * 1;


                var rowcount = options.zydata.length;
                //上半部
                var upDiv = jQuery("<div>", { "id": options.id +"headUp", "class": "GantChatHeaderDiv", "css": { "height": cellheight + "px"} });
                //下半部
                var downDiv = jQuery("<div>", { "id": options.id +"headDown", "class": "GantChatHeaderDiv", "css": { "top": cellheight + 1 + "px", "height": cellheight + "px"} });
                //甘特图内容
                gantbody = jQuery("<div>", { "id": options.id +"GantBody", "class": "GantChatBody" });

                switch (chattype) {
                    //按天        
                    default:
                        var months = [];
                        var date = startdate;
                        while (DateMethod.StringToDate(date.substr(0, 7) + '-15') <= DateMethod.StringToDate(enddate.substr(0, 7) + '-15')) {
                            months.push(date);
                            date = DateMethod.format(DateMethod.DateAdd(DateMethod.StringToDate(date), 'm', 1), "YYYY-MM-DD");
                        }
                        //甘特图的列数
                        var headcolumcount = 0;
                        for (var i = 0; i < months.length; i++) {
                            //生产甘特图表头第一行
                            var daycount = DateMethod.getDays(months[i].substr(0, 4), months[i].substr(5, 2));
                            var firstdaycount = 0;
                            //开始月份
                            if (i == '0') {
                                firstdaycount = DateMethod.daysBetween(startdate.substr(0, 7) + '-01', startdate);
                                upDiv.append(jQuery("<div>", { "class": "GantChatHeaderDiv_cell", "css": { "width": ((daycount - firstdaycount) * (cellWidth + 1) - 1) + "px", "height": cellheight + "px", "left": headcolumcount * (cellWidth + 1) + "px" } }).append(months[i].substr(0, 7)));
                            } else if (i == months.length - 1) {
                                //结束月份
                                var endwidth=DateMethod.daysBetween(enddate.substr(0, 7) + '-01', enddate)*1+1;
                                upDiv.append(jQuery("<div>", { "class": "GantChatHeaderDiv_cell", "css": { "width": (endwidth * (cellWidth + 1) - 1) + "px", "height": cellheight + "px", "left": headcolumcount * (cellWidth + 1) + "px" } }).append(months[i].substr(0, 7)));
                                daycount = endwidth;
                            }
                            else {
                                upDiv.append(jQuery("<div>", { "class": "GantChatHeaderDiv_cell", "css": { "width": ((daycount) * (cellWidth + 1) - 1) + "px", "height": cellheight + "px", "left": headcolumcount * (cellWidth + 1) + "px" } }).append(months[i].substr(0, 7)));
                            }
                            for (var m = 1 + firstdaycount*1; m <= daycount; m++) {
                                //生产甘特图表头第二行
                                var day = m <= 9 ? '0' + m : m;
                                var celldate = months[i].substr(0, 7) + "-" + day;
                                downDiv.append(jQuery("<div>", { "class": "GantChatHeaderDiv_cell", "css": { "width": cellWidth + "px", "height": cellheight + "px", "left": headcolumcount * (cellWidth + 1) + "px" } }).attr("celldate", celldate).append(m));
                                headcolumcount = headcolumcount + 1;
                            }
                        }
                        break;
                }
                //设置上下表头的宽度
                upDiv.css({ width: headcolumcount * (cellWidth + 1) + "px" });
                downDiv.css({ width: headcolumcount * (cellWidth + 1) + "px" });
                //生成甘特图中显示任务的行
                for (var i = 0; i < rowcount; i++) {
                    var datarow = $("<div>", { "id": options.id + "GantChatBodyDiv_row" + i, "zyname": options.zydata[i], "class": "GantChatBodyDiv_row", "css": { "width": headcolumcount * (cellWidth + 1) + "px", "height": cellheight + "px" } }).attr("YanGantid", options.id);
                    var rowtable = $("<table cellpadding='0' cellspacing='0'><tr></tr></table>");
                    $(".GantChatHeaderDiv_cell", downDiv).each(function (index) {
                        var date = $(this).attr("celldate");
                        var dayclass = "GantChatBody_Tasktd";
                        if (DateMethod.isWeekend(DateMethod.StringToDate(date))) {
                            dayclass = "GantChatBody_Tasktd GantChatBody_Tasktd_weekend";
                        }
                        var td = $("<td index='" + index + "'  title='" + date + "'  class='" + dayclass + "'  date='" + date + "' zyname='" + options.zydata[i] + "'></td>").css({ "width": cellWidth + "px", "height": cellheight + "px" });
                        if ($.isFunction(options.inittd)) {
                            options.inittd.call(this, td);
                        }
                        td.click(function (event) {
                            if ($.isFunction(options.tdclick)) {
                                options.tdclick.call(this, event);
                            }

                        });
                        $("tr", rowtable).append(td);
                    });
                    datarow.append(rowtable);
                    gantbody.append(datarow);
                }
                gantbody.css({ "top": cellheight * 2 + 2 + "px", "width": headcolumcount * (cellWidth + 1) + "px", "height": gantHeight - cellheight * 2 + 12 + "px" });
                gantobj.append(upDiv).append(downDiv).append(gantbody);
            }
        };

        var YanTableMethod = {
            addTable: function () {
                var zydata = options.zydata;
                var colmModel = options.colmModel;
                var cellheight = options.cellheight;
                var gantHeight = options.gantHeight * 1;

                //生成数据表格的头部
                var tableheader = jQuery("<div>", { "class": "GantDataHeaderDiv", "css": { "height": cellheight * 2 + 1 + "px"} });
                var headerleft = 0;
                tableheader.append(jQuery("<div>", { "class": "GantDataHeader_cell", "css": { "width": colmModel[0].width + "px", "height": cellheight * 2 + 1 + "px", "left": headerleft + "px"} }).append(colmModel[0].display));
                headerleft = headerleft + colmModel[0].width * 1 + 1;
                tableheader.css({ "width": headerleft + "px" });
                gantabletobj.append(tableheader);

                //生成数据表格的内容
                var tablecontent = jQuery("<div>", { "id": options.id +"YandataContent", "class": "YandataContent", "css": { "width": headerleft + "px", "height": gantHeight - cellheight * 2 + 12 * 1 + "px", "top": cellheight * 2 + 2 + "px"} });
                var datacelltop = 0;
                for (var m = 0; m < zydata.length; m++) {
                    var dataleft = 0;
                    var tabledata = jQuery("<div>", { "id": options.id +"GantDataDiv" + m, "class": "GantDataDiv", "isexp": "y", "css": { "height": cellheight + "px"} });
                    var GantData_cell = jQuery("<div>", { "class": "GantData_cell", "css": { "width": colmModel[0].width + "px", "line-height": cellheight + "px", "height": cellheight + "px", "left": dataleft + "px"} });
                    var divcontent = zydata[m];
                    tabledata.append(GantData_cell.append("<i  title='设置专业' zyname=" + zydata[m] + " class='icon-th-large zyset' style='margin-left: 20px;cursor:pointer'></i>" + divcontent));
                    dataleft = dataleft + colmModel[0].width * 1 + 1;
                    tabledata.css({ "width": dataleft + "px" });
                    datacelltop = datacelltop + cellheight * 1 + 1;
                    tablecontent.append(tabledata);
                }
                //生成数据表格的头部
                gantabletobj.append(tablecontent);


            }
        };

        this.each(function (Yancount) {
            thisTable.empty();
            options.id = thisTable.attr("id");
            thisTable.css({ "width": options.tablewidth * 1 + 1 + options.gantWidth * 1 + "px", "height": options.gantHeight * 1 + 30 + "px" }).addClass("dvYanGant");
            //甘特图标题栏

            //甘特图数据表格
            gantabletobj = jQuery("<div>", { "id": options.id +"Yandata", "class": "Yandata", "css": { "height": options.gantHeight * 1 + 30 + "px", "width": options.tablewidth + "px"} });
            YanTableMethod.addTable();

            //甘特图框架，+30是为了让滚动条内的内容全部看得见
            gantobj = jQuery("<div>", { "id": options.id +"YanGant", "class": "YanGant", "css": { "width": options.gantWidth + "px", "left": options.tablewidth + "px", "height": options.gantHeight * 1 + 30 + "px"} });
            YanGantMethod.addGantBody(options.chattype);
            //生成整个Gant表样式
            thisTable.prepend(gantobj).prepend(gantabletobj);
        });
        thisTable.data("option", options).data("YanGantMethod", YanGantMethod).data("YanTableMethod", YanTableMethod).fadeIn('normal');
        if ($.isFunction(options.gantcomplete)) {
            options.gantcomplete.call(this);
        }
    };
})(jQuery);
//按级别展开节点

